package piccolo;

import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Point;
import java.awt.event.InputEvent;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Vector;

import dbStruct.Column;
import dbStruct.DatabaseStructure;
import dbStruct.Node;
import dbStruct.Table;
import dbStruct.Node.NodeType;
import edu.umd.cs.piccolo.PCanvas;
import edu.umd.cs.piccolo.PNode;
import edu.umd.cs.piccolo.event.PDragEventHandler;
import edu.umd.cs.piccolo.event.PInputEvent;
import edu.umd.cs.piccolo.event.PInputEventFilter;
import edu.umd.cs.piccolo.nodes.PPath;

public class DragHandler extends PDragEventHandler {
	protected PCanvas canvas;
	protected PPath	  path;
	
	public DragHandler(PCanvas canvas)
	{
		this.canvas=canvas;
		setEventFilter(new PInputEventFilter(InputEvent.BUTTON1_MASK));
	}
	
	public void mousePressed(PInputEvent e)
	{
		super.mousePressed(e);
		
		if(e.getButton()==1) P2DCanvas.setCurrentShape(P2DCanvas.SHAPE_ENTITY);
		if(e.getButton()==3) P2DCanvas.setCurrentShape(P2DCanvas.SHAPE_RELATION);
		
		Point2D p = e.getPosition();
		float scale = (float) (1/e.getCamera().getViewScale());
		
		e.getInputManager().setKeyboardFocus(null);
	}
	
	public void mouseEntered(PInputEvent e)
	{
		super.mouseEntered(e);
		PNode p = e.getPickedNode();
		if (!(p instanceof PPath)) return;
		p.setPaint(Color.yellow);
	}
	
	public void mouseExited(PInputEvent e)
	{
		super.mouseExited(e);
		Color c = Color.white;
		PNode p = e.getPickedNode();
		if (!(p instanceof PPath)) return;
		int x = (int)p.getX();
		int y = (int)p.getY();
		int w = x + (int)p.getWidth();
		int h = y + (int)p.getHeight();
		int code = Integer.parseInt(p.getName());
		P2DNode node =  P2DCanvas.getInstance().getNodes().get(code);
		switch (node.getType())
		{
		case P2DNode.NODE_TYPE_ENTITY: 			c = Color.cyan;; break;
		case P2DNode.NODE_TYPE_RELATION: 		c = Color.green;; break;
		case P2DNode.NODE_TYPE_ATTRIBUTE: 		c = Color.orange;; break;
		case P2DNode.NODE_TYPE_GENERALIZATION: 	c = Color.blue;; break;
		case P2DNode.NODE_TYPE_EDGE: 			c = Color.black;; break;
		default: c = Color.black;
		}
		p.setPaint(new GradientPaint(new Point(x,y), c, new Point(w,h), Color.white));
	}
	
	protected void startDrag(PInputEvent e) {
        super.startDrag(e);
        e.setHandled(true);
        e.getPickedNode().moveToFront();
    }
    
    @SuppressWarnings("unchecked")
	protected void drag(PInputEvent e) {
    	int code = Integer.parseInt(e.getPickedNode().getName());
        P2DNode node = P2DCanvas.getInstance().getNodes().get(code);
    	if(node.getType()!=P2DNode.NODE_TYPE_EDGE)
        {
    		super.drag(e);
    		PNode pnode = e.getPickedNode();
    		Node  _node  = DatabaseStructure.getInstance().getNodes().getNodeFromPNode(pnode);
    		if(_node!=null)
    		{
	    		if(_node.getType()==NodeType.TABLE)
	    		{
	    			Table table = (Table) _node;
	    			Vector<Node> columns = DatabaseStructure.getInstance().getConnectors().getColumns(table.getName());
	    			for(int i=0;i<columns.size();i++)
	    			{
	    				Column column = (Column) columns.get(i);
	    				P2DCanvas.getInstance().updateColumns(column.getPNode(),pnode);
	    			}
	    		}
    		}
    		ArrayList<PNode> edges = (ArrayList) pnode.getAttribute(P2DCanvas.ARRAY_EDGES);
        	if (edges!=null)
        		for (int i=0; i<edges.size(); i++)
        		{
        			P2DCanvas.getInstance().updateEdge((PPath) edges.get(i));
        		}
        }
    }

	
	public void mouseDragged(PInputEvent e) {
        super.mouseDragged(e);
	}

	public void mouseReleased(PInputEvent e) {
        super.mouseReleased(e);

        // Update the squiggle one last time.
        updatePath(e);
        path = null;
	}
	
	public void updatePath(PInputEvent aEvent) {
        // Add a new segment to the squiggle
        // from the last mouse position to
        // the current mouse position.
        Point2D p = aEvent.getPosition();
        //path.lineTo((float) p.getX(), (float) p.getY());
	}

}
